
<!DOCTYPE html>
<html lang="">


<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
  <meta name="theme-color" content="#202020">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <script src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" async></script>
  
  
    <meta name="keywords" content>
  

  
    <meta name="description" content="第二十一章 Django的模型">
  
  
  
  <link rel="icon" type="image/x-icon" href="/images/footer-logo.png">
  
  <title>第二十一章 Django的模型 [ 51AIOps 专注于运维自动化  微信： kaipython ]</title>
  
    <!-- stylesheets list from config.yml -->
    
      <link rel="stylesheet" href="//cdn.bootcss.com/pure/1.0.0/pure-min.css">
    
      <link rel="stylesheet" href="/css/xoxo.css">
    
  
</head>


<body>
  <div class="nav-container">
    <nav class="home-menu pure-menu pure-menu-horizontal">
  <a class="pure-menu-heading" href="/">
    
    <span class="title" style="text-transform:none">51AIOps 专注于运维自动化  微信： kaipython</span>
  </a>

  <ul class="pure-menu-list clearfix">
      
          
            
              <li class="pure-menu-item"><a href="/" class="pure-menu-link">首页</a></li>
            
          
      
  </ul>
   
</nav>

  </div>

  <div class="container" id="content-outer">
    <div class="inner" id="content-inner" style='margin-left:-68px!important'>
      <div class="post-container">
  <article class="post" id="post">
    <header class="post-header text-center">
      <h1 class="title">
        第二十一章 Django的模型
      </h1>
      <span>
        
        <time class="time" datetime="2019-09-28T16:00:00.000Z">
        2019-09-29
      </time>
        
      </span>
      <span class="slash">/</span>
      <span class="post-meta">
      <span class="post-tags">
        
      </span>
    </span>
      <span class="slash">/</span>
      <span class="read">
      <span id="busuanzi_value_page_pv"></span> 点击
    </span>
      <span class="slash">/</span>
    </header>

    <div class="post-content">
      <h2 id="第二十一章-Django的模型"><a href="#第二十一章-Django的模型" class="headerlink" title="第二十一章 Django的模型"></a>第二十一章 Django的模型</h2><h3 id="Django-ORM"><a href="#Django-ORM" class="headerlink" title="Django ORM"></a>Django ORM</h3><h4 id="Django-模型使用自带的-ORM。"><a href="#Django-模型使用自带的-ORM。" class="headerlink" title="Django 模型使用自带的 ORM。"></a>Django 模型使用自带的 ORM。</h4><p>对象关系映射（Object Relational Mapping，简称 ORM ）用于实现面向对象编程语言里不同类型系统的数据之间的转换。<br>ORM 在业务逻辑层和数据库层之间充当了桥梁的作用。<br>ORM 是通过使用描述对象和数据库之间的映射的元数据，将程序中的对象自动持久化到数据库中。</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2020/05/django-orm1.png" alt="aaa"></p>
<p>ORM 对应关系表：<br><img src="https://www.runoob.com/wp-content/uploads/2020/05/orm-object.png" alt="aaa"></p>
<p>ORM 解析过程:</p>
<p>1、ORM 会将 Python 代码转成为 SQL 语句。<br>2、SQL 语句通过 pymysql 传送到数据库服务端。<br>3、在数据库中执行 SQL 语句并将结果返回。</p>
<p>使用 ORM 的好处：</p>
<ul>
<li>提高开发效率。</li>
<li>不同数据库可以平滑切换。</li>
<li>使用 ORM 的缺点：</li>
</ul>
<p>ORM 代码转换为 SQL 语句时，需要花费一定的时间，执行效率会有所降低。<br>长期写 ORM 代码，会降低编写 SQL 语句的能力。</p>
<hr>

<h4 id="数据库配置"><a href="#数据库配置" class="headerlink" title="数据库配置"></a>数据库配置</h4><p>Django 如何使用 mysql 数据库<br>创建 MySQL 数据库( ORM 无法操作到数据库级别，只能操作到数据表)语法：</p>
<blockquote>
<p>create database 数据库名称 default charset=utf8; # 防止编码问题，指定为 utf8</p>
</blockquote>
<p>我们在项目的 settings.py 文件中找到 DATABASES 配置项，将其信息修改为：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">DATABASES = &#123; </span><br><span class="line">    <span class="string">'default'</span>: </span><br><span class="line">    &#123; </span><br><span class="line">        <span class="string">'ENGINE'</span>: <span class="string">'django.db.backends.mysql'</span>,    <span class="comment"># 数据库引擎</span></span><br><span class="line">        <span class="string">'NAME'</span>: <span class="string">'test'</span>, <span class="comment"># 数据库名称</span></span><br><span class="line">        <span class="string">'HOST'</span>: <span class="string">'127.0.0.1'</span>, <span class="comment"># 数据库地址，本机 ip 地址 127.0.0.1 </span></span><br><span class="line">        <span class="string">'PORT'</span>: <span class="number">3306</span>, <span class="comment"># 端口 </span></span><br><span class="line">        <span class="string">'USER'</span>: <span class="string">'root'</span>,  <span class="comment"># 数据库用户名</span></span><br><span class="line">        <span class="string">'PASSWORD'</span>: <span class="string">'123456'</span>, <span class="comment"># 数据库密码</span></span><br><span class="line">    &#125;  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>接下来，告诉 Django 使用 pymysql 模块连接 mysql 数据库：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 在与 settings.py 同级目录下的 __init__.py 中引入模块和进行配置 </span></span><br><span class="line"><span class="keyword">import</span> pymysql</span><br><span class="line">pymysql.install_as_MySQLdb()</span><br></pre></td></tr></table></figure>

<h4 id="定义模型"><a href="#定义模型" class="headerlink" title="定义模型"></a>定义模型</h4><p>创建 APP<br>Django 规定，如果要使用模型，必须要创建一个 app。我们使用以下命令创建一个 app01 的 app:</p>
<blockquote>
<p>django-admin.py startapp app01</p>
</blockquote>
<p>我们修改 TestModel/models.py 文件，代码如下：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># models.py</span></span><br><span class="line"><span class="keyword">from</span> django.db <span class="keyword">import</span> models</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Book</span><span class="params">(models.Model)</span>:</span> </span><br><span class="line">    id = models.AutoField(primary_key=<span class="literal">True</span>) <span class="comment"># id 会自动创建,可以手动写入</span></span><br><span class="line">    title = models.CharField(max_length=<span class="number">32</span>) <span class="comment"># 书籍名称</span></span><br><span class="line">    price = models.DecimalField(max_digits=<span class="number">5</span>, decimal_places=<span class="number">2</span>) <span class="comment"># 书籍价格 </span></span><br><span class="line">    publish = models.CharField(max_length=<span class="number">32</span>) <span class="comment"># 出版社名称 </span></span><br><span class="line">    pub_date = models.DateField() <span class="comment"># 出版时间</span></span><br></pre></td></tr></table></figure>

<p>以上的类名代表了数据库表名，且继承了models.Model，类里面的字段代表数据表中的字段(name)，数据类型则由CharField（相当于varchar）、DateField（相当于datetime）， max_length 参数限定长度。</p>
<p>接下来在 settings.py 中找到INSTALLED_APPS这一项，如下</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">INSTALLED_APPS = (</span><br><span class="line">    <span class="string">'django.contrib.admin'</span>,</span><br><span class="line">    <span class="string">'django.contrib.auth'</span>,</span><br><span class="line">    <span class="string">'django.contrib.contenttypes'</span>,</span><br><span class="line">    <span class="string">'django.contrib.sessions'</span>,</span><br><span class="line">    <span class="string">'django.contrib.messages'</span>,</span><br><span class="line">    <span class="string">'django.contrib.staticfiles'</span>,</span><br><span class="line">    <span class="string">'app01'</span>,               <span class="comment"># 添加此项</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure>

<p>在命令行中运行：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ python3 manage.py makemigrations app01  <span class="comment"># 让 Django 知道我们在我们的模型有一些变更</span></span><br><span class="line">$ python3 manage.py migrate app01   <span class="comment"># 创建表结构</span></span><br></pre></td></tr></table></figure>

<p>看到几行 “Creating table…” 的字样，你的数据表就创建好了。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Creating tables ...</span><br><span class="line">……</span><br><span class="line">Creating table TestModel_test  <span class="comment">#我们自定义的表</span></span><br><span class="line">……</span><br></pre></td></tr></table></figure>

<p>表名组成结构为：应用名_类名（如：app01_Book）。</p>
<p>注意：尽管我们没有在 models 给表设置主键，但是 Django 会自动添加一个 id 作为主键。</p>
<h4 id="常见报错信息"><a href="#常见报错信息" class="headerlink" title="常见报错信息"></a>常见报错信息</h4><p>如果执行以上命令时会出现如下报错信息:<br><img src="https://www.runoob.com/wp-content/uploads/2020/05/Django-orm_5.png" alt="aaa"><br>原因是 MySQLclient 目前只支持到 Python3.4，因此如果使用的更高版本的 python，需要修改如下：</p>
<p>通过报错信息的文件路径找到 …site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql 这个路径里的 base.py 文件，把这两行代码注释掉（代码在文件开头部分）：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> version &lt; (<span class="number">1</span>, <span class="number">3</span>, <span class="number">13</span>):</span><br><span class="line">    <span class="keyword">raise</span> ImproperlyConfigured(<span class="string">'mysqlclient 1.3.13 or newer is required; you have %s.'</span> % Database.__version__)</span><br></pre></td></tr></table></figure>

<p>一般点报错的代码文件路径信息，会自动跳转到报错文件中行数，此时我们在报错的代码行数注释掉。</p>
<p>如果出现以下报错信息:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2020/05/Django-orm_6.png" alt="aaa"></p>
<p>我们点报错的代码文件路径，跳转到报错文件中行数，此时我们在报错的代码行数之前加上:</p>
<blockquote>
<p>query = query.encode()</p>
</blockquote>
<h4 id="数据库操作-增删改查"><a href="#数据库操作-增删改查" class="headerlink" title="数据库操作 (增删改查)"></a>数据库操作 (增删改查)</h4><p>接下来我们在 HelloWorld 目录中添加 testdb.py 文件（下面介绍），并修改 urls.py：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line"><span class="keyword">from</span> django.urls <span class="keyword">import</span> path</span><br><span class="line"><span class="keyword">from</span> . <span class="keyword">import</span> views</span><br><span class="line"> </span><br><span class="line">urlpatterns = [</span><br><span class="line">    path(<span class="string">'add_book/'</span>, views.add_book),</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<h5 id="添加数据"><a href="#添加数据" class="headerlink" title="添加数据"></a>添加数据</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">### 第一种添加方式</span></span><br><span class="line">    book = models.Book(title=<span class="string">"python教程"</span>,price=<span class="number">300</span>,publish=<span class="string">"51aiops出版社"</span>,pub_date=<span class="string">"2018-8-8"</span>) </span><br><span class="line">    book.save()</span><br><span class="line">    </span><br><span class="line">    <span class="comment">### 第二种添加方式    </span></span><br><span class="line">    books = models.Book.objects.create(title=<span class="string">"如来神掌"</span>,price=<span class="number">200</span>,publish=<span class="string">"功夫出版社"</span>,pub_date=<span class="string">"2010-10-10"</span>) </span><br><span class="line">    print(books, type(books)) <span class="comment"># Book object (18) </span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;数据添加成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<h5 id="获取数据"><a href="#获取数据" class="headerlink" title="获取数据"></a>获取数据</h5><p>Django提供了多种方式来获取数据库的内容，如下代码所示：</p>
<p>1.使用 all() 方法来查询所有内容。</p>
<p>返回的是 QuerySet 类型数据，类似于 list，里面放的是一个个模型类的对象，可用索引下标取出模型类的对象。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    books = models.Book.objects.all() </span><br><span class="line">    print(books,type(books)) <span class="comment"># QuerySet类型，类似于list，访问 url 时数据显示在命令行窗口中。</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>id<br>2.get() 方法用于查询符合条件的返回模型类的对象符合条件的对象只能为一个，如果符合筛选条件的对象超过了一个或者没有一个都会抛出错误</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    books = models.Book.objects.get(id=<span class="number">5</span>)</span><br><span class="line">    books = models.Book.objects.get(id=<span class="number">18</span>)  <span class="comment"># 报错，没有符合条件的对象</span></span><br><span class="line">    books = models.Book.objects.get(price=<span class="number">200</span>)  <span class="comment"># 报错，符合条件的对象超过一个</span></span><br><span class="line">    print(books, type(books))  <span class="comment"># 模型类的对象</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>3.values() 方法用于查询部分字段的数据。</p>
<p>返回的是 QuerySet 类型数据，类似于 list，里面不是模型类的对象，而是一个可迭代的字典序列，字典里的键是字段，值是数据。<br>注意：</p>
<ul>
<li>参数的字段名要加引号</li>
<li>想要字段名和数据用 values</li>
</ul>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    <span class="comment"># 查询所有的id字段和price字段的数据 </span></span><br><span class="line">    books = models.Book.objects.values(<span class="string">"id"</span>,<span class="string">"price"</span>) </span><br><span class="line">    print(books[<span class="number">0</span>][<span class="string">"price"</span>],type(books)) <span class="comment"># 得到的是第一条记录的price字段的数据</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>4.filter() 方法用于查询符合条件的数据。</p>
<p>返回的是 QuerySet 类型数据，类似于 list，里面放的是满足条件的模型类的对象，可用索引下标取出模型类的对象。<br>id</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    books = models.Book.objects.filter(id=<span class="number">5</span>)</span><br><span class="line">    print(books)</span><br><span class="line">    print(<span class="string">"//////////////////////////////////////"</span>)</span><br><span class="line">    books = models.Book.objects.filter(publish=<span class="string">'51aiops出版社'</span>, price=<span class="number">300</span>)</span><br><span class="line">    print(books, type(books))  <span class="comment"># QuerySet类型，类似于list。</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>filter() 方法基于双下划线的模糊查询（exclude 同理）。<br>注意：filter 中运算符号只能使用等于号 = ，不能使用大于号 &gt; ，小于号 &lt; ，等等其他符号。<br>__in 用于读取区间，= 号后面为列表 。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    <span class="comment"># 查询价格为200或者300的数据 </span></span><br><span class="line">    books = models.Book.objects.filter(price__in=[<span class="number">200</span>,<span class="number">300</span>])</span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="comment">## __gt 大于号 ，= 号后面为数字。</span></span><br><span class="line">    <span class="comment"># 查询价格大于200的数据 </span></span><br><span class="line">    books = models.Book.objects.filter(price__gt=<span class="number">200</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="comment"># __gte 大于等于，= 号后面为数字。</span></span><br><span class="line">    <span class="comment"># 查询价格大于等于200的数据 </span></span><br><span class="line">    books = models.Book.objects.filter(price__gte=<span class="number">200</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="comment"># __lt 小于，=号后面为数字</span></span><br><span class="line">    books=models.Book.objects.filter(price__lt=<span class="number">300</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="comment"># __lte 小于等于，= 号后面为数字。</span></span><br><span class="line">    <span class="comment"># 查询价格小于等于300的数据 </span></span><br><span class="line">    books=models.Book.objects.filter(price__lte=<span class="number">300</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="comment"># __range 在 ... 之间，左闭右闭区间，= 号后面为两个元素的列表。</span></span><br><span class="line">    books=models.Book.objects.filter(price__range=[<span class="number">200</span>,<span class="number">300</span>])</span><br><span class="line">    </span><br><span class="line">    <span class="comment"># __contains 包含，= 号后面为字符串。</span></span><br><span class="line">    books=models.Book.objects.filter(title__contains=<span class="string">"菜"</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="comment">#__icontains 不区分大小写的包含，= 号后面为字符串。</span></span><br><span class="line">    books=models.Book.objects.filter(title__icontains=<span class="string">"python"</span>) <span class="comment"># 不区分大小写</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># __startswith 以指定字符开头，= 号后面为字符串。</span></span><br><span class="line">    books=models.Book.objects.filter(title__startswith=<span class="string">"菜"</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="comment"># __endswith 以指定字符结尾，= 号后面为字符串。</span></span><br><span class="line">    books=models.Book.objects.filter(title__endswith=<span class="string">"教程"</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="comment"># __year 是 DateField 数据类型的年份，= 号后面为数字。</span></span><br><span class="line">    books=models.Book.objects.filter(pub_date__year=<span class="number">2008</span>) </span><br><span class="line">    </span><br><span class="line">    <span class="comment"># __month 是DateField 数据类型的月份，= 号后面为数字</span></span><br><span class="line">    books=models.Book.objects.filter(pub_date__month=<span class="number">10</span>) </span><br><span class="line">    </span><br><span class="line">    <span class="comment">#__day 是DateField 数据类型的天数，= 号后面为数字。</span></span><br><span class="line">    books=models.Book.objects.filter(pub_date__day=<span class="number">01</span>)</span><br></pre></td></tr></table></figure>

<p>5.exclude() 方法用于查询不符合条件的数据。</p>
<p>返回的是 QuerySet 类型数据，类似于 list，里面放的是不满足条件的模型类的对象，可用索引下标取出模型类的对象。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    books = models.Book.objects.exclude(id=<span class="number">5</span>)</span><br><span class="line">    print(books)</span><br><span class="line">    print(<span class="string">"//////////////////////////////////////"</span>)</span><br><span class="line">    books = models.Book.objects.exclude(publish=<span class="string">'51aiops出版社'</span>, price=<span class="number">300</span>)</span><br><span class="line">    print(books, type(books))  <span class="comment"># QuerySet类型，类似于list。</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>6.order_by() 方法用于对查询结果进行排序。</p>
<p>返回的是 QuerySet类型数据，类似于list，里面放的是排序后的模型类的对象，可用索引下标取出模型类的对象。<br>注意：<br>a、参数的字段名要加引号。<br>b、降序为在字段前面加个负号 -。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    books = models.Book.objects.order_by(<span class="string">"price"</span>) <span class="comment"># 查询所有，按照价格升序排列 </span></span><br><span class="line">    books = models.Book.objects.order_by(<span class="string">"-price"</span>) <span class="comment"># 查询所有，按照价格降序排列</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>7.count() 方法用于查询数据的数量返回的数据是整数。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    books = models.Book.objects.count() <span class="comment"># 查询所有数据的数量 </span></span><br><span class="line">    books = models.Book.objects.filter(price=<span class="number">200</span>).count() <span class="comment"># 查询符合条件数据的数量</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>8.first() 方法返回第一条数据返回的数据是模型类的对象也可以用索引下标 [0]。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    books = models.Book.objects.first() <span class="comment"># 返回所有数据的第一条数据</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>9.last() 方法返回最后一条数据返回的数据是模型类的对象不能用索引下标 [-1]，ORM 没有逆序索引。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    books = models.Book.objects.last() <span class="comment"># 返回所有数据的最后一条数据</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>10.exists() 方法用于判断查询的结果 QuerySet 列表里是否有数据。</p>
<p>返回的数据类型是布尔，有为 true，没有为 false。</p>
<p>注意：判断的数据类型只能为 QuerySet 类型数据，不能为整型和模型类的对象。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    books = models.Book.objects.exists() </span><br><span class="line">    <span class="comment"># 报错，判断的数据类型只能为QuerySet类型数据，不能为整型 </span></span><br><span class="line">    books = models.Book.objects.count().exists()</span><br><span class="line">    <span class="comment"># 报错，判断的数据类型只能为QuerySet类型数据，不能为模型类对象 </span></span><br><span class="line">    books = models.Book.objects.first().exists()  </span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>11.values_list() 方法用于查询部分字段的数据。</p>
<p>返回的是 QuerySet 类型数据，类似于 list，里面不是模型类的对象，而是一个个元组，元组里放的是查询字段对应的数据。<br>注意：</p>
<ul>
<li>参数的字段名要加引号</li>
<li>只想要数据用 values_list</li>
</ul>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    <span class="comment"># 查询所有的price字段和publish字段的数据 </span></span><br><span class="line">    books = models.Book.objects.values_list(<span class="string">"price"</span>,<span class="string">"publish"</span>) </span><br><span class="line">    print(books)</span><br><span class="line">    print(books[<span class="number">0</span>][<span class="number">0</span>],type(books)) <span class="comment"># 得到的是第一条记录的price字段的数据</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>12.distinct() 方法用于对数据进行去重。<br>返回的是 QuerySet 类型数据。<br>注意：<br>对模型类的对象去重没有意义，因为每个对象都是一个不一样的存在。<br>distinct() 一般是联合 values 或者 values_list 使用。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    <span class="comment"># 查询一共有多少个出版社 </span></span><br><span class="line">    books = models.Book.objects.values_list(<span class="string">"publish"</span>).distinct() <span class="comment"># 对模型类的对象去重没有意义，因为每个对象都是一个不一样的存在。 </span></span><br><span class="line">    books = models.Book.objects.distinct()</span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;查找成功！&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<p>13.原生的SQL语句操作</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.db <span class="keyword">import</span> connection</span><br><span class="line"></span><br><span class="line">cursor=connection.cursor()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 插入操作</span></span><br><span class="line">cursor.execute(<span class="string">"insert into hello_author(name) values('钱钟书')"</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 更新操作</span></span><br><span class="line">cursor.execute(<span class="string">"update hello_author set name='abc' where name='bcd'"</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除操作</span></span><br><span class="line">cursor.execute(<span class="string">"delete from hello_author where name='abc'"</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查询操作</span></span><br><span class="line">cursor.execute(<span class="string">"select * from hello_author"</span>)</span><br><span class="line"></span><br><span class="line">raw=cursor.fetchone()  <span class="comment"># 返回结果行游标直读向前，读取一条</span></span><br><span class="line">cursor.fetchall()  <span class="comment"># 读取所有</span></span><br></pre></td></tr></table></figure>

<h5 id="更新数据"><a href="#更新数据" class="headerlink" title="更新数据"></a>更新数据</h5><p>修改数据可以使用 save() 或 update():</p>
<blockquote>
<p>QuerySet 类型数据.update(字段名=更改的数据)（推荐）</p>
</blockquote>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render,HttpResponse</span><br><span class="line"><span class="keyword">from</span> app01 <span class="keyword">import</span> models </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_book</span><span class="params">(request)</span>:</span></span><br><span class="line">    books = models.Book.objects.filter(id__in=[<span class="number">7</span>,<span class="number">8</span>]).update(price=<span class="number">888</span>)</span><br><span class="line">    <span class="keyword">return</span> HttpResponse(books)</span><br></pre></td></tr></table></figure>

<blockquote>
<p>模型类的对象.属性 = 更改的属性值<br>模型类的对象.save()</p>
</blockquote>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">books = models.Book.objects.filter(id=<span class="number">7</span>).first() </span><br><span class="line">books.price = <span class="number">400</span> books.save()</span><br></pre></td></tr></table></figure>

<h5 id="删除数据"><a href="#删除数据" class="headerlink" title="删除数据"></a>删除数据</h5><p>删除数据库中的对象只需调用该对象的delete()方法即可：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">from</span> django.http <span class="keyword">import</span> HttpResponse</span><br><span class="line"> </span><br><span class="line"><span class="keyword">from</span> TestModel.models <span class="keyword">import</span> Test</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 数据库操作</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">testdb</span><span class="params">(request)</span>:</span></span><br><span class="line">    <span class="comment"># 删除id=1的数据</span></span><br><span class="line">    test1 = Test.objects.get(id=<span class="number">1</span>)</span><br><span class="line">    test1.delete()</span><br><span class="line">    </span><br><span class="line">    <span class="comment"># 另外一种方式</span></span><br><span class="line">    <span class="comment"># Test.objects.filter(id=1).delete()</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment"># 删除所有数据</span></span><br><span class="line">    <span class="comment"># Test.objects.all().delete()</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"&lt;p&gt;删除成功&lt;/p&gt;"</span>)</span><br></pre></td></tr></table></figure>

<h4 id="高级查询"><a href="#高级查询" class="headerlink" title="高级查询"></a>高级查询</h4><h5 id="1-聚合查询（aggregate）"><a href="#1-聚合查询（aggregate）" class="headerlink" title="1.聚合查询（aggregate）"></a>1.聚合查询（aggregate）</h5><p>聚合查询函数是对一组值执行计算，并返回单个值。</p>
<p>Django 使用聚合查询前要先从 django.db.models 引入 Avg、Max、Min、Count、Sum（首字母大写）。</p>
<blockquote>
<p>from django.db.models import Avg,Max,Min,Count,Sum  #   引入函数</p>
</blockquote>
<p>聚合查询返回值的数据类型是字典。</p>
<p>聚合函数 aggregate() 是 QuerySet 的一个终止子句， 生成的一个汇总值，相当于 count()。</p>
<p>使用 aggregate() 后，数据类型就变为字典，不能再使用 QuerySet 数据类型的一些 API 了。</p>
<p>返回的字典中：键的名称默认是（属性名称加上__聚合函数名），值是计算出来的聚合值。</p>
<p>如果要自定义返回字典的键的名称，可以起别名：</p>
<blockquote>
<p>aggregate(别名 = 聚合函数名(“属性名称”))</p>
</blockquote>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.db.models <span class="keyword">import</span> Avg,Max,Min,Count,Sum  <span class="comment">#   引入函数</span></span><br><span class="line">...</span><br><span class="line"></span><br><span class="line"><span class="comment">### 1.计算所有图书的平均价格:</span></span><br><span class="line">res = models.Book.objects.aggregate(Avg(<span class="string">"price"</span>))</span><br><span class="line">print(res, type(res))</span><br><span class="line"></span><br><span class="line"><span class="comment">### 2.计算所有图书的数量、最贵价格和最便宜价格:</span></span><br><span class="line">res=models.Book.objects.aggregate(c=Count(<span class="string">"id"</span>),max=Max(<span class="string">"price"</span>),min=Min(<span class="string">"price"</span>)) </span><br><span class="line">print(res,type(res)</span><br></pre></td></tr></table></figure>

<h5 id="分组查询（annotate）"><a href="#分组查询（annotate）" class="headerlink" title="分组查询（annotate）"></a>分组查询（annotate）</h5><p>分组查询一般会用到聚合函数，所以使用前要先从 django.db.models 引入 Avg,Max,Min,Count,Sum（首字母大写）。</p>
<blockquote>
<p>from django.db.models import Avg,Max,Min,Count,Sum  #   引入函数</p>
</blockquote>
<p>返回值：</p>
<ul>
<li>分组后，用 values 取值，则返回值是 QuerySet 数据类型里面为一个个字典；</li>
<li>分组后，用 values_list 取值，则返回值是 QuerySet 数据类型里面为一个个元组。</li>
</ul>
<p>MySQL 中的 limit 相当于 ORM 中的 QuerySet 数据类型的切片。</p>
<p>注意：</p>
<p>annotate 里面放聚合函数。</p>
<p>values 或者 values_list 放在 annotate 前面：values 或者 values_list 是声明以什么字段分组，annotate 执行分组。</p>
<p>values 或者 values_list 放在annotate后面： annotate 表示直接以当前表的id执行分组，values 或者 values_list 表示查询哪些字段， 并且要将 annotate 里的聚合函数起别名，在 values 或者 values_list 里写其别名。</p>
<p>例子：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 查询根据日期统计一下每本书的价格</span></span><br><span class="line">ret = models.Book.objects.values(<span class="string">"pub_date"</span>).annotate(total=Sum(<span class="string">'price'</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment">### 分组完成之后进行having过滤</span></span><br><span class="line">ret = models.Book.objects.values(<span class="string">"pub_date"</span>).annotate(total=Sum(<span class="string">'price'</span>)).filter(total__gt=<span class="number">200</span>)</span><br></pre></td></tr></table></figure>

<p><strong>注意：values放在前面和放在后面的区别</strong></p>
<h5 id="2-F-查询"><a href="#2-F-查询" class="headerlink" title="2.F() 查询"></a>2.F() 查询</h5><p>F() 的实例可以在查询中引用字段，来比较同一个 model 实例中两个不同字段的值。</p>
<p>之前构造的过滤器都只是将字段值与某个常量做比较，如果想要对两个字段的值做比较，就需要用到 F()。</p>
<p>使用前要先从 django.db.models 引入 F:</p>
<blockquote>
<p>from django.db.models import F</p>
</blockquote>
<p>用法：</p>
<blockquote>
<p>F(“字段名称”)</p>
</blockquote>
<p>F 动态获取对象字段的值，可以进行运算。</p>
<p>Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取余的操作。</p>
<p>修改操作（update）也可以使用 F() 函数。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 1. 将每一本书的价格提高100元:</span></span><br><span class="line">res = models.Book.objects.update(price=F(<span class="string">"price"</span>)+<span class="number">100</span>)</span><br><span class="line">print(res)</span><br></pre></td></tr></table></figure>

<h5 id="3-Q-查询"><a href="#3-Q-查询" class="headerlink" title="3.Q() 查询"></a>3.Q() 查询</h5><p>使用前要先从 django.db.models 引入 Q:</p>
<blockquote>
<p>from django.db.models import Q<br>Q(条件判断)</p>
</blockquote>
<p>之前构造的过滤器里的多个条件的关系都是 and，如果需要执行更复杂的查询（例如 or 语句），就可以使用 Q 。</p>
<p>Q 对象可以使用 &amp; | ~ （与 或 非）操作符进行组合。</p>
<p>优先级从高到低：~ &amp; |。</p>
<p>可以混合使用 Q 对象和关键字参数，Q 对象和关键字参数是用”and”拼在一起的（即将逗号看成 and ），但是 Q 对象必须位于所有关键字参数的前面。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.db.models <span class="keyword">import</span> Q</span><br><span class="line"></span><br><span class="line"><span class="comment">## 1. 查询价格大于 350 或者名称以菜开头的书籍的名称和价格。</span></span><br><span class="line">res=models.Book.objects.filter(Q(price__gt=<span class="number">350</span>)|Q(title__startswith=<span class="string">"菜"</span>)).values(<span class="string">"title"</span>,<span class="string">"price"</span>)</span><br><span class="line">print(res)</span><br><span class="line"></span><br><span class="line"><span class="comment">## 2. 查询出版日期是 2004 或者 1999 年，并且书名中包含有"菜"的书籍。</span></span><br><span class="line">Q 对象和关键字混合使用，Q 对象要在所有关键字的前面:</span><br><span class="line"></span><br><span class="line">res = models.Book.objects.filter(Q(pub_date__year=<span class="number">2004</span>) | Q(pub_date__year=<span class="number">1999</span>), title__contains=<span class="string">"菜"</span>)</span><br><span class="line">print(res)</span><br></pre></td></tr></table></figure>

<h3 id="Django-models-的常用字段类型和字段参数"><a href="#Django-models-的常用字段类型和字段参数" class="headerlink" title="Django models 的常用字段类型和字段参数"></a>Django models 的常用字段类型和字段参数</h3><p><strong>常用字段类型</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line">&lt;<span class="number">1</span>&gt; CharField</span><br><span class="line"> <span class="comment">#字符串字段, 用于较短的字符串.</span></span><br><span class="line"> <span class="comment">#CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所允许的最大字符数.</span></span><br><span class="line"></span><br><span class="line">&lt;<span class="number">2</span>&gt; IntegerField</span><br><span class="line">       <span class="comment">#用于保存一个整数.</span></span><br><span class="line"></span><br><span class="line">&lt;<span class="number">3</span>&gt; FloatField</span><br><span class="line">        <span class="comment"># 一个浮点数. 必须 提供两个参数:</span></span><br><span class="line">        <span class="comment">#</span></span><br><span class="line">        <span class="comment"># 参数    描述</span></span><br><span class="line">        <span class="comment"># max_digits    总位数(不包括小数点和符号)</span></span><br><span class="line">        <span class="comment"># decimal_places    小数位数</span></span><br><span class="line">                <span class="comment"># 举例来说, 要保存最大值为 999 (小数点后保存2位),你要这样定义字段:</span></span><br><span class="line">                <span class="comment">#</span></span><br><span class="line">                <span class="comment"># models.FloatField(..., max_digits=5, decimal_places=2)</span></span><br><span class="line"></span><br><span class="line">&lt;<span class="number">4</span>&gt; AutoField</span><br><span class="line">        <span class="comment"># 一个 IntegerField, 添加记录时它会自动增长. 你通常不需要直接使用这个字段; </span></span><br><span class="line">        <span class="comment"># 自定义一个主键：my_id=models.AutoField(primary_key=True)</span></span><br><span class="line">        <span class="comment"># 如果你不指定主键的话,系统会自动添加一个主键字段到你的 model.</span></span><br><span class="line"></span><br><span class="line">&lt;<span class="number">5</span>&gt; TextField</span><br><span class="line">        <span class="comment"># 一个容量很大的文本字段.</span></span><br><span class="line">        <span class="comment"># admin 用一个 &lt;textarea&gt; (文本区域)表示该字段数据.(一个多行编辑框).</span></span><br><span class="line"></span><br><span class="line">&lt;<span class="number">6</span>&gt; EmailField</span><br><span class="line">        <span class="comment"># 一个带有检查Email合法性的 CharField,不接受 maxlength 参数.        </span></span><br><span class="line">  			<span class="comment">#（仅仅在admin中有意义...)</span></span><br><span class="line"></span><br><span class="line">&lt;<span class="number">7</span>&gt; DateField</span><br><span class="line">        <span class="comment"># 一个日期字段. 共有下列额外的可选参数:</span></span><br><span class="line">        <span class="comment"># Argument    描述</span></span><br><span class="line">        <span class="comment"># auto_now    当对象被保存时,自动将该字段的值设置为当前时间.通常用于表示 "last-modified" 时间戳.</span></span><br><span class="line">        <span class="comment"># auto_now_add    当对象首次被创建时,自动将该字段的值设置为当前时间.通常用于表示对象创建时间.</span></span><br><span class="line"> </span><br><span class="line">&lt;<span class="number">8</span>&gt; DateTimeField</span><br><span class="line">        <span class="comment">#  一个日期时间字段. 类似 DateField 支持同样的附加选项.</span></span><br><span class="line"></span><br><span class="line">&lt;<span class="number">9</span>&gt; URLField</span><br><span class="line">      <span class="comment"># 用于保存 URL. 若 verify_exists 参数为 True (默认), 给定的 URL 会预先检查是否存在( 即URL是否被有效装入且</span></span><br><span class="line">      <span class="comment"># 没有返回404响应).</span></span><br><span class="line">      <span class="comment"># admin 用一个 &lt;input type="text"&gt; 文本框表示该字段保存的数据(一个单行编辑框)</span></span><br><span class="line"></span><br><span class="line">&lt;<span class="number">10</span>&gt; NullBooleanField</span><br><span class="line">       <span class="comment"># 类似 BooleanField, 不过允许 NULL 作为其中一个选项. 推荐使用这个字段而不要用 BooleanField 加 null=True 选项</span></span><br><span class="line">       <span class="comment"># admin 用一个选择框 &lt;select&gt; (三个可选择的值: "Unknown", "Yes" 和 "No" ) 来表示这种字段数据.</span></span><br><span class="line"></span><br><span class="line">&lt;<span class="number">11</span>&gt; IPAddressField</span><br><span class="line">        <span class="comment"># 一个字符串形式的 IP 地址, (i.e. "24.124.1.30").</span></span><br></pre></td></tr></table></figure>

<p><strong>常见的参数</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1</span>、null=<span class="literal">True</span></span><br><span class="line">　　　　数据库中字段是否可以为空</span><br><span class="line"><span class="number">2</span>、blank=<span class="literal">True</span></span><br><span class="line">　　django的 Admin 中添加数据时是否可允许空值</span><br><span class="line"><span class="number">3</span>、primary_key = <span class="literal">False</span></span><br><span class="line">　　主键，对AutoField设置主键后，就会代替原来的自增 id 列</span><br><span class="line"><span class="number">4</span>、auto_now 和 auto_now_add</span><br><span class="line">　　auto_now   自动创建---无论添加或修改，都是当前操作的时间</span><br><span class="line">　　auto_now_add  自动创建---永远是创建时的时间</span><br><span class="line"><span class="number">5</span>、choices</span><br><span class="line">GENDER_CHOICE = (</span><br><span class="line">        (<span class="string">u'M'</span>, <span class="string">u'Male'</span>),</span><br><span class="line">        (<span class="string">u'F'</span>, <span class="string">u'Female'</span>),</span><br><span class="line">    )</span><br><span class="line">gender = models.CharField(max_length=<span class="number">2</span>,choices = GENDER_CHOICE) </span><br><span class="line">　　这里我们用在内存创建一个关联,来取代再创建一个简单的表来关联</span><br><span class="line"><span class="number">6</span>、max_length</span><br><span class="line"><span class="number">7</span>、default　　默认值</span><br><span class="line"><span class="number">8</span>、verbose_name　　Admin中字段的显示名称</span><br><span class="line"><span class="number">9</span>、unique=<span class="literal">True</span>　　不允许重复  例如用户名注册时候是不允许重复的,在username字段里设置,不让重复</span><br><span class="line"><span class="number">10</span>、db_index = <span class="literal">True</span>　　数据库索引    </span><br><span class="line"><span class="number">11</span>、editable=<span class="literal">True</span>　　在Admin里是否可编辑</span><br><span class="line"><span class="number">12</span>、help_text　　在Admin中提示帮助信息</span><br></pre></td></tr></table></figure>


    </div>

  </article>
  <div class="toc-container">
    
  <div id="toc" class="toc-article">
    <strong class="toc-title">目录</strong>
    <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#第二十一章-Django的模型"><span class="toc-text">第二十一章 Django的模型</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Django-ORM"><span class="toc-text">Django ORM</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Django-模型使用自带的-ORM。"><span class="toc-text">Django 模型使用自带的 ORM。</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#数据库配置"><span class="toc-text">数据库配置</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#定义模型"><span class="toc-text">定义模型</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#常见报错信息"><span class="toc-text">常见报错信息</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#数据库操作-增删改查"><span class="toc-text">数据库操作 (增删改查)</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#添加数据"><span class="toc-text">添加数据</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#获取数据"><span class="toc-text">获取数据</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#更新数据"><span class="toc-text">更新数据</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#删除数据"><span class="toc-text">删除数据</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#高级查询"><span class="toc-text">高级查询</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#1-聚合查询（aggregate）"><span class="toc-text">1.聚合查询（aggregate）</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#分组查询（annotate）"><span class="toc-text">分组查询（annotate）</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#2-F-查询"><span class="toc-text">2.F() 查询</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#3-Q-查询"><span class="toc-text">3.Q() 查询</span></a></li></ol></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Django-models-的常用字段类型和字段参数"><span class="toc-text">Django models 的常用字段类型和字段参数</span></a></li></ol></li></ol>
  </div>


  </div>
</div>
<script type="text/javascript" src="//rf.revolvermaps.com/0/0/8.js?i=5sr5du46f27&amp;m=0&amp;c=ff0000&amp;cr1=ffffff&amp;f=arial&amp;l=33" async="async"></script>
<div class="copyright">
    <span>本作品采用</span>
    <a href="https://creativecommons.org/licenses/by/4.0/">知识共享署名 4.0 国际许可协议</a>
    <span>进行许可。 转载时请注明原文链接。</span>
</div>


  
    <div class="post-nav" style="margin-left:-168px;">
      <div class="post-nav-item post-nav-next">
        
          <span>〈 </span>
          <a href="/2019/09/29/Djangoorm多表实例/" rel="next" title="第二十二章 Django ORM-多表实例">
          第二十二章 Django ORM-多表实例
          </a>
        
      </div>
  
      <div class="post-nav-item post-nav-prev">
          
          <a href="/2019/10/08/Devops和sre/" rel="prev" title="DevOps 和 SRE 的定义和异同">
            DevOps 和 SRE 的定义和异同
          </a>
          <span>〉</span>
        
      </div>
    </div>
  


	
	<div style="width:109%; margin-left:-144px" id="lv-container" data-id="city" data-uid="MTAyMC80OTg5NS8yNjM4Ng==">
	<script type="text/javascript">
   	   (function(d, s) {
       		var j, e = d.getElementsByTagName(s)[0];

       		if (typeof LivereTower === 'function') { return; }

       		j = d.createElement(s);
       		j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
       		j.async = true;

       		e.parentNode.insertBefore(j, e);
   	   })(document, 'script');
	</script>
	<noscript> 为正常使用来必力评论功能请激活JavaScript</noscript>
        </div>
	



    </div>

    

  </div>
  <footer class="footer text-center">
    <div id="bottom-inner">
        <a class="bottom-item" href target="_blank">GitHub</a> |
        <a class="bottom-item" href>友情链接</a> |
        <a class="bottom-item" href="https://hexo.io" target="_blank">Powered by hexo</a> |
        <a class="bottom-item" href="https://github.com/fooying/hexo-theme-xoxo-plus" target="_blank">Theme xoxo-plus</a> |
        <a class="bottom-item" href="/atom.xml">订阅</a>
    </div>
</footer>

  

<script>
  (function(window, document, undefined) {

    var timer = null;

    function returnTop() {
      cancelAnimationFrame(timer);
      timer = requestAnimationFrame(function fn() {
        var oTop = document.body.scrollTop || document.documentElement.scrollTop;
        if (oTop > 0) {
          document.body.scrollTop = document.documentElement.scrollTop = oTop - 50;
          timer = requestAnimationFrame(fn);
        } else {
          cancelAnimationFrame(timer);
        }
      });
    }

    var hearts = [];
    window.requestAnimationFrame = (function() {
      return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function(callback) {
          setTimeout(callback, 1000 / 60);
        }
    })();
    init();

    function init() {
      css(".heart{z-index:9999;width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: absolute;}.heart:after{top: -5px;}.heart:before{left: -5px;}");
      attachEvent();
      gameloop();
      addMenuEvent();
    }

    function gameloop() {
      for (var i = 0; i < hearts.length; i++) {
        if (hearts[i].alpha <= 0) {
          document.body.removeChild(hearts[i].el);
          hearts.splice(i, 1);
          continue;
        }
        hearts[i].y--;
        hearts[i].scale += 0.004;
        hearts[i].alpha -= 0.013;
        hearts[i].el.style.cssText = "left:" + hearts[i].x + "px;top:" + hearts[i].y + "px;opacity:" + hearts[i].alpha + ";transform:scale(" + hearts[i].scale + "," + hearts[i].scale + ") rotate(45deg);background:" + hearts[i].color;
      }
      requestAnimationFrame(gameloop);
    }

    /**
     * 给logo设置点击事件
     * 
     * - 回到顶部
     * - 出现爱心
     */
    function attachEvent() {
      var old = typeof window.onclick === "function" && window.onclick;
      var logo = document.getElementById("logo");
      if (logo) {
        logo.onclick = function(event) {
          returnTop();
          old && old();
          createHeart(event);
        }
      }
      
    }

    function createHeart(event) {
      var d = document.createElement("div");
      d.className = "heart";
      hearts.push({
        el: d,
        x: event.clientX - 5,
        y: event.clientY - 5,
        scale: 1,
        alpha: 1,
        color: randomColor()
      });
      document.body.appendChild(d);
    }

    function css(css) {
      var style = document.createElement("style");
      style.type = "text/css";
      try {
        style.appendChild(document.createTextNode(css));
      } catch (ex) {
        style.styleSheet.cssText = css;
      }
      document.getElementsByTagName('head')[0].appendChild(style);
    }

    function randomColor() {
      // return "rgb(" + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) + ")";
      return "#F44336";
    }

    function addMenuEvent() {
      var menu = document.getElementById('menu-main-post');
      if (menu) {
        var toc = document.getElementById('toc');
        if (toc) {
          menu.onclick = function() {
            if (toc) {
              if (toc.style.display == 'block') {
                toc.style.display = 'none';
              } else {
                toc.style.display = 'block';
              }
            }
          };
        } else {
          menu.style.display = 'none';
        }
      }
    }

  })(window, document);
</script>

  



  

</body>
</html>
